<?php

###############   COPYLEFT GPLv3 LICENSE   ###############
##
## JFX Version 0.2.9
## Website Management Software
## www.jfxcms.com
##
## Copyright 2009 GPLv3 - http://www.opensource.org/licenses/gpl-3.0.html
##
## Anthony Gallon
## oi_antz@hotmail.com
##
## Permission is hereby granted to any person having a copy of this software
## to freely use and modify as required so long as the copyright notices
## and branding remain intact.
##
## Full license details available at http://www.jfxcms.com/license
##
###############   COPYLEFT GPLv3 LICENSE   ###############

class JFX_Module_Core extends JFX_Module {

	public $id = 1;
	public $keyname = 'core';
	public $title = 'JFX Core';
	public $version = '0.2.9';

	public function __construct() {
		parent::__construct();
		$CONFIG = JFX::registry('config');
		$THEME = JFX::registry('JFX_Theme');
		$CONFIG->adminActionsDir = $this->dirname . '/actions';
		$CONFIG->jsUrl = $THEME->jsUrl;
		$CONFIG->cssUrl = $THEME->cssUrl;
		$CONFIG->imageUrl = $CONFIG->baseUrl . '/jfx/images/' . $THEME->keyname;
		$this->title = $this->lang('module_title');
		//$this->resetLanguages();
	}

	public function editPageDetails($details) {

		$BLOCK = new JFX_Block;
		$BLOCK->loadById($details->id, $details->pageid);
		$pageid = $BLOCK->pageid;

		$_GET['page'] = $pageid;

		$DB = JFX::registry('db');

		$CONFIG = JFX::registry('config');
		$VIEW = JFX::registry('JFX_View');
		$USER = JFX::registry('JFX_User');
		$SMARTY = JFX::registry('Smarty');
		$LINKER = JFX::registry('Linker');
		$THEME = JFX::registry('JFX_Theme');
		$LANG = JFX::registry('lang');
		$SETTINGS = JFX::registry('JFX_Settings');
		$CRYPT = JFX::registry('JFX_Crypt');

		include($this->dirname . '/actions/ajax/edit-page.php');
	}

	public function dispatch() {
		global $JFXMemDebug;


//        error_reporting(E_ALL);
		//       $MM = JFX::registry('JFX_Module_Manager');
		//     $MM->rebuildHookCache();
		//   echo 'done';
		// return;
//$this->resetLanguages();
//echo 'done';
//return;
		$DB = JFX::registry('db');
		$CONFIG = JFX::registry('config');
		$VIEW = JFX::registry('JFX_View');
		$USER = JFX::registry('JFX_User');
		$SMARTY = JFX::registry('Smarty');
		$LINKER = JFX::registry('Linker');
		$THEME = JFX::registry('JFX_Theme');
		$LANG = JFX::registry('lang');
		$SETTINGS = JFX::registry('JFX_Settings');
		$CRYPT = JFX::registry('JFX_Crypt');

		// work out our page request
		$requestUri = explode('?', THIS_PAGE_URL);
		$requestUri = str_replace($CONFIG->baseUrl, '', $requestUri[0]);
		$requestUri = explode('/', trim($requestUri, '/'));
		$prefix = explode('/', trim($CONFIG->prefix, '/'));
		foreach ($requestUri as $k => $v) {
			if (array_key_exists($k, $prefix) && $v == $prefix[$k])
				unset($requestUri[$k]);
		}
		$requestUri = array_regenerate_keys($requestUri);


		$JFXMemDebug[] = array('bytes' => memory_get_usage(), 'file' => __FILE__, 'line' => __LINE__, 'time' => getmicrotime(), 'desc' => 'After calculating request');

		$thisFolder = '';
		if (array_key_exists(0, $requestUri))
			$thisFolder = $requestUri[0];
		//echo $thisFolder;return;

		$SMARTY->assign('USER', JFX::objectToArray($USER));

		$JFXMemDebug[] = array('bytes' => memory_get_usage(), 'file' => __FILE__, 'line' => __LINE__, 'time' => getmicrotime(), 'desc' => 'After setting user to smarty');

		$this->addJsLink('config.php');

		$eParams = array(
		    'thisFolder' => $thisFolder
		);
		JFX::hook('JFX_Core.dispatchPre', $eParams);

		$SMARTY->assign(array(
		    'baseUrl' => $CONFIG->baseUrl,
		    'imageUrl' => $CONFIG->imageUrl,
		    'adminUrl' => $CONFIG->adminUrl,
		    'jsUrl' => $CONFIG->jsUrl,
		    'cssUrl' => $CONFIG->cssUrl,
		    'thisPageUrl' => THIS_PAGE_URL
		));



		if ($thisFolder === trim($CONFIG->adminFolder, '/')) {
			// display the backend
			require($this->dirname . '/jfx-admin.php');

			$JFXMemDebug[] = array('bytes' => memory_get_usage(), 'file' => __FILE__, 'line' => __LINE__, 'time' => getmicrotime(), 'desc' => 'After jfx-admin');
		} elseif ($thisFolder == trim($CONFIG->moduleCssFolder, '/')) {
			// serve module-specific css
			require($this->dirname . '/jfx-module-css-server.php');

			$JFXMemDebug[] = array('bytes' => memory_get_usage(), 'file' => __FILE__, 'line' => __LINE__, 'time' => getmicrotime(), 'desc' => 'After jfx-module-css-server');
		} elseif ($thisFolder == trim($CONFIG->moduleJsFolder, '/')) {
			// serve module-specific js
			require($this->dirname . '/jfx-module-js-server.php');

			$JFXMemDebug[] = array('bytes' => memory_get_usage(), 'file' => __FILE__, 'line' => __LINE__, 'time' => getmicrotime(), 'desc' => 'After jfx-module-js-server');
		} elseif ($thisFolder == trim($CONFIG->moduleImageFolder, '/')) {
			// serve module-specific images
			require($this->dirname . '/jfx-module-image-server.php');

			$JFXMemDebug[] = array('bytes' => memory_get_usage(), 'file' => __FILE__, 'line' => __LINE__, 'time' => getmicrotime(), 'desc' => 'After jfx-module-image-server');
		} elseif ($thisFolder == trim($CONFIG->moduleServerFolder, '/')) {
			require($this->dirname . '/jfx-module-server.php');

			$JFXMemDebug[] = array('bytes' => memory_get_usage(), 'file' => __FILE__, 'line' => __LINE__, 'time' => getmicrotime(), 'desc' => 'After jfx-module-server');
		} elseif ($thisFolder == trim($CONFIG->themeServerFolder, '/')) {
			require($this->dirname . '/jfx-theme-server.php');

			$JFXMemDebug[] = array('bytes' => memory_get_usage(), 'file' => __FILE__, 'line' => __LINE__, 'time' => getmicrotime(), 'desc' => 'After jfx-theme-server');
		} else {

			// display the CMS to public user
			require_once($this->dirname . '/jfx-cms-render.php');

			$JFXMemDebug[] = array('bytes' => memory_get_usage(), 'file' => __FILE__, 'line' => __LINE__, 'time' => getmicrotime(), 'desc' => 'After jfx-cms-render');
		}
	}

	public function getTemplatesAsArray() {
		$SETTINGS = JFX::registry('JFX_Settings');
		$pageid = $SETTINGS->get('template_page_id');
		$block = JFX_Block::getBlockById($pageid, $pageid);
		return $block->elements;
	}

	public function getBlockActionButtons($blockid, $pageid='') {
		$CONFIG = JFX::registry('config');
		$block = JFX_Block::getBlockById($blockid, $pageid);

		$allButtons = array();

		if ($this->checkPermission('perm_edit_block') && $block->canMoveUp()) {
			// move up button
			$button1 = new JFX_Block_Button;
			$button1->pageId = $pageid;
			$button1->alternativeText = $this->lang('button_move_up_alt');
			$button1->moduleName = 'core';
			$button1->moduleMethod = 'decrementBlock';
			$button1->imageUrl = $CONFIG->imageUrl . '/admin/icons/up.png';
			$button1->title = $this->lang('button_move_up_title');
			$button1->blockId = $blockid;
			$button1->invisible = true;
			$button1->rebuildPage = true;
			$allButtons[] = $button1;
		}
		if ($this->checkPermission('perm_edit_block') && $block->canMoveDown()) {
			// move down button
			$button1 = new JFX_Block_Button;
			$button1->pageId = $pageid;
			$button1->alternativeText = $this->lang('button_move_down_alt');
			$button1->moduleName = 'core';
			$button1->moduleMethod = 'incrementBlock';
			$button1->imageUrl = $CONFIG->imageUrl . '/admin/icons/down.png';
			$button1->title = $this->lang('button_move_down_title');
			$button1->blockId = $blockid;
			$button1->invisible = true;
			$button1->rebuildPage = true;
			$allButtons[] = $button1;
		}

		if ($this->checkPermission('perm_create_blocks') && $block->canInsert()) {
			// can insert button
			$button1 = new JFX_Block_Button;
			$button1->pageId = $pageid;
			$button1->alternativeText = $this->lang('button_insert_alt');
			$button1->moduleName = 'core';
			$button1->moduleMethod = 'insertBlock';
			$button1->imageUrl = $CONFIG->imageUrl . '/admin/icons/plus-green.png';
			$button1->title = $this->lang('button_insert_title');
			$button1->blockId = $blockid;
			$allButtons[] = $button1;
		}
		if ($this->checkPermission('perm_delete_block') && $block->canDelete()) {
			// can delete button
			$button1 = new JFX_Block_Button;
			$button1->pageId = $pageid;
			$button1->alternativeText = $this->lang('button_delete_alt');
			$button1->moduleName = 'core';
			$button1->moduleMethod = 'deleteBlock';
			$button1->imageUrl = $CONFIG->imageUrl . '/admin/icons/delete.png';
			$button1->title = $this->lang('button_delete_title');
			$button1->blockId = $blockid;
			$button1->invisible = true;
			$button1->rebuildPage = true;
			$allButtons[] = $button1;
		}
		return $allButtons;
	}

	public function insertBlock($block, $pageId) {
		$DB = JFX::registry('db');
		$CONFIG = JFX::registry('config');
		$VIEW = JFX::registry('JFX_View');
		$USER = JFX::registry('JFX_User');
		$SMARTY = JFX::registry('Smarty');
		$THEME = JFX::registry('JFX_Theme');
		$SETTINGS = JFX::registry('JFX_Settings');
		require($this->dirname . '/actions/ajax/insert-block.php');
	}

	public function getPageActionButtons($blockId, $pageid) {

		$CONFIG = JFX::registry('config');

		$allButtons = array();

		$page = JFX_Block::getBlockById($pageid, $pageid);

		if ($this->checkPermission('perm_edit_page') && $page->canInsert()) {
			// can insert button
			$button1 = new JFX_Page_Button;
			$button1->alternativeText = $this->lang('button_edit_alt');
			$button1->moduleName = 'core';
			$button1->moduleMethod = 'editPageDetails';
			$button1->imageUrl = $CONFIG->imageUrl . '/admin/icons/edit.gif';
			$button1->title = $this->lang('button_edit_title');
			$button1->pageId = $pageid;
			$button1->id = $blockId;
			$button1->blockId = $blockId;
			$allButtons[] = $button1;
		}


		if ($this->checkPermission('perm_create_blocks') && $page->canInsert()) {
			// can insert button
			$button1 = new JFX_Page_Button;
			$button1->alternativeText = $this->lang('button_insert_alt');
			$button1->moduleName = 'core';
			$button1->moduleMethod = 'insertBlock';
			$button1->imageUrl = $CONFIG->imageUrl . '/admin/icons/plus-green.png';
			$button1->title = $this->lang('button_insert_title');
			$button1->pageId = $pageid;
			$button1->id = $blockId;
			$button1->blockId = $blockId;
			$allButtons[] = $button1;
		}

		return $allButtons;
	}

	public function getBlockEditButtons($block) {
		$CONFIG = JFX::registry('config');
		$button1 = new JFX_Block_Button;
		$button1->pageId = $block->pageid;
		$button1->alternativeText = $this->lang('button_style_alt');
		$button1->moduleName = 'core';
		$button1->moduleMethod = 'updateStyle';
		$button1->imageUrl = $CONFIG->imageUrl . '/admin/icons/style.gif';
		$button1->title = $this->lang('button_style_title');
		$button1->blockId = $block->id;
		return array($button1);
	}

	public function incrementBlock($block) {
		$block->moveDown();
	}

	public function decrementBlock($block) {
		$block->moveUp();
	}

	public function deleteBlock($block) {
		$block->delete();
	}

	public function install() {
		include($this->dirname . '/install/install.php');
	}

	public function updateStyle($block, $pageId) {
		require($this->dirname . '/actions/ajax/style-block.php');
	}

	public function importPage($FILE, $parentid=0) {
		$DB = JFX::registry('db');
		$CONFIG = JFX::registry('config');
		$USER = JFX::registry('JFX_User');
		$error = false;

		if ($parentid == 0)
			$parentid = (int) post('parentFrom');
		if ($parentid == 0) {
			// load a default parent id
			$parentid = $DB->oneValue($CONFIG->dbprefix . 'pages', 'id', "is_default = 1 AND workspace_id = '{$USER->workspace}'");
			if ($parentid == 0) {
				$parentid = $DB->oneValue($CONFIG->dbprefix . 'pages', 'id', 'is_default = 1');
				if ($parentid == 0) {
					JFX::addError($this->lang('error_no_default_page'));
					return false;
				}
			}
		}

		if (false === $FILE->load($_FILES['file']['tmp_name'])) {
			JFX::addError('Failed to load file');
			$error = true;
		} else {
			if ($FILE->get('type') != 'page_export') {
				JFX::addError('Invalid file type');
				$error = true;
			} else {
				$page = unserialize($FILE->get('content'));
				if (!is_array($page)) {
					$error = true;
					JFX::addError('Failed to read file content');
				}
			}

			if (isset($page['d']) && is_array($page['d'])) {
				// check module dependencies
				$deps = $page['d'];
				foreach ($deps as $k => $v) {
					if (!JFX_Module::isInstalled($v)) {
						JFX::addError('Required module "' . $v . '" is not installed');
						$error = true;
					}
				}
			}
		}




		if (!$error) {
			$domainid = $DB->oneValue($CONFIG->dbprefix . 'pages', 'domain_id', "id = '{$parentid}'");
			JFX_ImportPage_DecompressPage($page, $parentid, $domainid);
			return true;
		} else {
			return false;
		}
	}

	public function exportPage($pageid, $filename) {
		$DB = JFX::registry('db');
		$CONFIG = JFX::registry('config');
		$USER = JFX::registry('JFX_User');

		$deps = array();

		$page = $DB->fetchRow("SELECT * FROM {$CONFIG->dbprefix}pages WHERE id = '{$pageid}'");
		$page['subpages'] = JFX::getPageTree($pageid, $USER->workspace);

		$pageCompressed = JFX_ExportPage_CompressPage($page, $deps);
		$pageCompressed = serialize($pageCompressed);

		$pageTitle = $this->getContent('heading', $pageid);

		$fParams = array(
		    'type' => 'page_export',
		    'title' => $pageTitle,
		    'description' => 'File export of page "' . $pageTitle . '"',
		    'module' => $this->keyname,
		    'method' => 'importPage',
		    'url' => '/export/import-page/',
		    'core_minimum_version' => '0.2.4',
		    'theme_minimum_version' => '0.2.4',
		    'module_minimum_version' => '0.2.4',
		    'content' => $pageCompressed
		);

		$FILE = new JFX_File;
		$FILE->set($fParams);
		return $FILE->save($filename);
	}

	public function exportBlock($blockid, $filename) {
		$DB = JFX::registry('db');
		$CONFIG = JFX::registry('config');
		$USER = JFX::registry('JFX_User');

		$blocks = $DB->fetchAll("SELECT * FROM {$CONFIG->dbprefix}blocks WHERE id = '{$blockid}' AND is_template = 1");

		foreach ($blocks as $k => $v) {
			$blocks[$k] = JFX_ExportBlock_GetBlockDetails($v, $v['page_id'], $USER->workspace);
		}

		$blocksCompressed = serialize($blocks);

		$blockTitle = JFX_Block::getTitleById($blockid);

		$fParams = array(
		    'type' => 'block_export',
		    'title' => $blockTitle,
		    'description' => 'File export of page "' . $blockTitle . '"',
		    'module' => $this->keyname,
		    'method' => 'importBlock',
		    'url' => '/export/import-block/',
		    'core_minimum_version' => '0.2.4',
		    'theme_minimum_version' => '0.2.4',
		    'module_minimum_version' => '0.2.4',
		    'content' => $blocksCompressed
		);

		$FILE = new JFX_File;
		$FILE->set($fParams);
		return $FILE->save($filename);
	}

	public function importBlock($FILE, $parentid=0) {
		$DB = JFX::registry('db');
		$CONFIG = JFX::registry('config');
		$USER = JFX::registry('JFX_User');

		if ($parentid == 0)
			$parentid = (int) post('parentFrom');
		if ($parentid == 0) {
			// load a default parent id
			$parentid = $DB->oneValue($CONFIG->dbprefix . 'pages', 'id', "is_default = 1 AND workspace_id = '{$USER->workspace}'");
			if ($parentid == 0) {
				$parentid = $DB->oneValue($CONFIG->dbprefix . 'pages', 'id', 'is_default = 1');
				if ($parentid == 0) {
					JFX::addError($this->lang('error_no_default_page'));
					return false;
				}
			}
		}



		$blocks = unserialize($FILE->get('content'));

		if (!is_array($blocks)) {
			$error = true;
			JFX::addError($this->lang('invalid_file'));
		}

		if (!$error) {
			foreach ($blocks as $k => $blockDetails) {
				JFX_ImportBlock_ImportBlocks($blockDetails, $parentid, $parentid);
			}
			return true;
		}
		return false;
	}

	public function addTemplate($title, $code) {
		$DB = JFX::registry('db');
		$CONFIG = JFX::registry('config');
		$SETTINGS = JFX::registry('JFX_Settings');

		$dom = phpQuery::newDocumentXhtml($code);

		$headscript = (string) pq('>script', $dom);
		$headstyle = (string) pq('>style', $dom);
		pq('>script', $dom)->remove();
		pq('>style', $dom)->remove();

		$divs = pq('>div', $dom);

		if (count($divs->elements) > 1) {
			JFX::addError($this->lang('can_only_have_one_root_div'));
			return false;
		}

		if (count($divs->elements) == 0) {
			JFX::addError($this->lang('no_root_div'));
			return false;
		}

		$droppables = pq('.droppable', $divs);
		foreach ($droppables->elements as $k => $droppableEl) {
			if (strtolower($droppableEl->nodeName) != 'div') {
				JFX::addError($this->lang('cannot_use_droppabe_class'));
				return false;
			}
		}

		$rootDiv = pq($divs->elements[0]);
		$rootDivEl = $divs->elements[0];

		$rootBlock = JFX_Block::newModuleBlock('content', 'content');

		$parentid = 'jfxpage-' . $SETTINGS->get('template_page_id');

		$id = $parentid . '-content-0';
		while ($DB->countRows($CONFIG->dbprefix . 'blocks', "id = '{$id}' AND page_id = '" . $SETTINGS->get('template_page_id') . "'") > 0) {
			$ids = explode('-', $id);
			$ids[count($ids) - 1]++;
			$id = implode('-', $ids);
		}

		$blockDetails = array(
		    'id' => $id,
		    'title' => $title,
		    'workspace_id' => 1,
		    'parent_id' => $parentid,
		    'module_key' => 'content',
		    'module_action' => 'content',
		    'sorting' => '',
		    'page_parent' => 1,
		    'class_name' => trim(str_replace('droppable', '', $rootDivEl->getAttribute('class'))),
		    'ajax_enabled' => '0',
		    'is_droppable' => (bool) $rootDiv->hasClass('droppable'),
		    'page_id' => $SETTINGS->get('template_page_id'),
		    'exec_order' => '0',
		    'template' => '',
		    'block_style' => '',
		    'is_template' => 1,
		    'template_style' => '',
		    'template_script' => '',
		    'template_style' => $headstyle,
		    'template_script' => $headscript
		);

		$rootBlock->setDetails($blockDetails);

		$rootBlock->save();

		$this->addTemplate_saveBlocks($rootDiv, $rootBlock);

		return true;
	}

	function addTemplate_saveBlocks($element, $parentBlock) {
		$DB = JFX::registry('db');
		$CONFIG = JFX::registry('config');
		$USER = JFX::registry('JFX_User');
		$SETTINGS = JFX::registry('JFX_Settings');

		$elements = array();

		$parentId = $parentBlock->id;

		//$DB->debug(true);
		//$DB->showErrors(true);
		$childElements = pq('>div', $element);

		foreach ($childElements as $k => $v) {
			$v = pq($v);

			$block = JFX_Block::newModuleBlock('content', 'content');

			$id = 'jfxpage-' . $SETTINGS->get('template_page_id') . '-content-0';
			while ($DB->countRows($CONFIG->dbprefix . 'blocks', "id = '{$id}' AND page_id = '" . $SETTINGS->get('template_page_id') . "'") > 0) {
				$ids = explode('-', $id);
				$ids[count($ids) - 1]++;
				$id = implode('-', $ids);
			}

			$bData = array(
			    'id' => $id,
			    'parent_id' => $parentBlock->id,
			    'module_key' => 'content',
			    'module_action' => 'content',
			    'sorting' => $k,
			    'workspace_id' => 1,
			    'page_parent' => 0,
			    'class_name' => trim(str_replace('droppable', '', $v->elements[0]->getAttribute('class'))),
			    'ajax_enabled' => '0',
			    'is_droppable' => (int) (bool) $v->hasClass('droppable'),
			    'page_id' => $SETTINGS->get('template_page_id'),
			    'exec_order' => '0',
			    'template' => '',
			    'block_style' => '',
			    'is_template' => 0,
			    'template_style' => '',
			    'template_script' => ''
			);

			if (false === $block->setDetails($bData))
				die('error setting details');
			$block->save();

			if (isset($v->childNodes) && count($v->childNodes) > 0) {
				$block->elements = $this->addTemplate_saveBlocks($v, $block);
				$block->save();
			};

			$elements[] = $block;
		}

		//$DB->showErrors(false);
		return $elements;
		//$DB->debug(false);
	}

}

